ig.module('plugins.tween').defines(function(){
    "use strict";
    
    /* 
     Tween
     ------Create------
     var entityTween = new ig.Tween(this.entity,{x:300,y:300},0.3);
     ------Use------
     in game ->
     update:function(){
     this.parent();
     for(var i=0;i<ig.Tween.tweens.length;i++){
     ig.Tween.tweens[i].update();
     }
     }
     */
    ig.Tween = ig.Class.extend({
        target: undefined,
        duration: 0.3,
        props: undefined,
        lastUpdateTime: undefined,
        startTime: undefined,
        endTime: undefined,
        completed: undefined,
        init: function(target, props, duration, completed){
            this.target = target;
            this.props = props;
            this.duration = duration * 1000;
            this.completed = completed ||
            function(){
            };
            ig.Tween.tweens.push(this);
        },
        update: function(){
            if (!this.startTime) {
                this.startTime = new Date();
                this.endTime = new Date().setMilliseconds(this.startTime.getMilliseconds() + this.duration);
                this.lastUpdateTime = this.startTime;
            }
            
            //剩余多少时间完成任务
            var se_trace = this.endTime - this.lastUpdateTime;
            //上次任务与今次任务之间相隔的时间
            var nl_trace = new Date() - this.lastUpdateTime;
            //按照上次任务与今次任务之间相隔的时间计算出有多少次任务需要执行
            var trace_step = se_trace / nl_trace;
            
            if (nl_trace == 0) {
                return;
            }
            else {
                if (trace_step <= 0) {
                    this._setPropValuesToTarget(this.props, this.target, trace_step);
                    //强制完成任务
                    this._completed();
                    return;
                }
                else {
                    //执行任务
                    this._setPropValues(this.props, this.target, trace_step);
                }
            }
            
            this.lastUpdateTime = new Date();
        },
        _setPropValuesToTarget: function(props, target, trace_step){
            for (var prop in props) {
                if (typeof(props[prop]) == 'object') {
                    for (var subProp in props[prop]) {
                        target[prop][subProp] = props[prop][subProp];
                    }
                }
                else {
                    target[prop] = props[prop];
                }
            }
        },
        _setPropValues: function(props, target, trace_step){
            for (var prop in props) {
                if (typeof(props[prop]) == 'object') {
                    for (var subProp in props[prop]) {
                        this._setPropValue(props[prop], target[prop], subProp, trace_step);
                    }
                }
                else {
                    this._setPropValue(props, target, prop, trace_step);
                }
            }
        },
        _setPropValue: function(props, target, prop, trace_step){
            var target_value = props[prop];
            var source_value = target[prop];
            var trace_value = target_value - source_value;
            var each_step_value = Math.floor(trace_value / trace_step);
            
            if (trace_value > 0) {
                if (source_value + each_step_value > target_value) 
                    target[prop] = source_value;
                else 
                    target[prop] = source_value + each_step_value;
            }
            else {
                if (source_value + each_step_value < target_value) 
                    target[prop] = source_value;
                else 
                    target[prop] = source_value + each_step_value;
            }
        },
        _completed: function(){
            ig.Tween.tweens.erase(this);
            this.completed();
        }
    });
    ig.Tween.tweens = new Array();
});
